'----------------------------------------------
' Name: Ali Karbassi
'       Matt Latzke
'       Chris Hanegraaf
'       Brian Culp
' Date: May 1, 2007
' Description: Program 8
'              Public Class Reader
'----------------------------------------------
Imports System.Threading

''' <summary>
''' Reader Class
''' </summary>
''' <remarks></remarks>
Public Class Reader
   Implements ReaderWriter

   Private display As PassMessage
   Private readerThread As Thread
   Private generator As New Random(Now.Millisecond)
   Private _mainForm As Form
   Private readerEvent As New AutoResetEvent(False)

   ''' <summary>
   ''' Sets the delegate
   ''' </summary>
   ''' <value></value>
   ''' <remarks></remarks>
   Private WriteOnly Property DisplayMsg() As PassMessage Implements ReaderWriter.DisplayMsg
      Set(ByVal value As PassMessage)
         display = value
      End Set
   End Property

   ''' <summary>
   ''' Sets the main form
   ''' </summary>
   ''' <value></value>
   ''' <remarks></remarks>
   Private WriteOnly Property mainForm() As Form Implements ReaderWriter.mainForm
      Set(ByVal value As Form)
         _mainForm = value
      End Set
   End Property

   ''' <summary>
   ''' Returns the ID
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Private ReadOnly Property ID() As String Implements ReaderWriter.ID
      Get
         Return "Reader AK" & readerThread.GetHashCode
      End Get
   End Property

   ''' <summary>
   ''' Returns the type
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Private ReadOnly Property type() As ReaderWriterType Implements ReaderWriter.type
      Get
         Return ReaderWriterType.Reader
      End Get
   End Property

   ''' <summary>
   ''' Creates a new thread and starts it.
   ''' </summary>
   ''' <remarks></remarks>
   Private Sub SpinUp() Implements ReaderWriter.SpinUp
      readerThread = New Thread(AddressOf Run)
      readerThread.Start()
   End Sub

   ''' <summary>
   ''' Wakes up the event.
   ''' </summary>
   ''' <remarks></remarks>
   Public Sub WakeUp() Implements ReaderWriter.WakeUp
      readerEvent.Set()
   End Sub

   ''' <summary>
   ''' Runs the reader.
   ''' </summary>
   ''' <remarks></remarks>
   Private Sub run()

      Monitor.Enter(Q)
      Q.Enqueue(Me)
      Monitor.Exit(Q)

      _mainForm.Invoke(display, ID, State.Wait, CShort(_total))

      readerEvent.Reset()
      managerEvent.Set()
      readerEvent.WaitOne()

      Monitor.Enter(DataObj)
      RC += 1
      Monitor.Exit(DataObj)

      _mainForm.Invoke(display, ID, State.Start, CShort(_total))

      Thread.Sleep(generator.Next(1000, 5000))

      Monitor.Enter(DataObj)
      RC -= 1
      If RC = 0 Then
         managerEvent.Set()
      End If
      Monitor.Exit(DataObj)

      _mainForm.Invoke(display, ID, State.Finish, CShort(_total))

   End Sub

End Class
